package org.ogv.usada.states;

import org.ogv.OGV;
import org.ogv.usada.models.Content;
import org.ogv.usada.models.GP;
import org.ogv.usada.models.LevelDef;
import org.ogv.usada.models.LevelDef.LevelRep;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;

public class LevelSelectScreen extends ScreenState {
	private TextureRegion 	_bg;
	private TextureRegion 	_star;
	private LevelRep		_lastLr;
	private Rectangle		_tempRect;
	private Sprite			_exitBtn;
	
	public LevelSelectScreen(SpriteBatch sb) {
		super(sb);
		_id 		= GP.$().STATE_LEVEL_SELECT;
		_tempRect 	= new Rectangle();
	}
	
	@Override
	public void init() {
		_bg 		= OGV.asset.getTextureRegion(GP.$().RES_TEXR_LVSEL_BG);
		_star		= OGV.asset.getTextureRegion(GP.$().RES_TEXR_LVSEL_STAR);
		_exitBtn	= new Sprite(OGV.asset.getTextureRegion(GP.$().RES_TEXR_LVSEL_EXIT));
		_exitBtn.setPosition(GP.$().GAME_WIDTH - _exitBtn.getWidth() - 60, 60);
		
		//Doors
		initializeDoors();
		resume();
	}
	
	@Override
	public void resume() {
		_bgm = OGV.asset.get("data/audio/bgm-map.mp3", Music.class);
		_bgm.play();
		_bgm.setLooping(true);
		_bgm.setVolume(GP.$().MUSIC_VOL);
		startOpeningDoor();
	}
	
	@Override
	public void pause() {
		_bgm.stop();
	}
	
	@Override
	public void destroy() {
		pause();
	}
	
	@Override
	public void run(float elapsedTime) {
		if(areDoorsActive())
			updateDoors(elapsedTime);
		else
			update(elapsedTime);
		
		//Drawing
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		_sb.begin();
		
		//Normal Draw
		draw();
		
		//Draw doors
		//if(isDoorsActive())
			drawDoors();
		
		_sb.end();
	}

	private void draw() {
		//Draw bg
		_sb.draw(_bg, 0, 0);
		
		//Draw exit btn
		_exitBtn.draw(_sb);
		
		//Draw each level rep
		LevelDef[] lvs 	= Content.$().levels;
		int latestLevel = Content.$().latestLevel;
		for(int i = 0; i <= latestLevel; ++i) {
			LevelRep lr = lvs[i].levelRep;
			drawLevelRep(lr, i);
		}
	}

	private void drawLevelRep(LevelRep lr, int lvIdx) {
		float posX = lr.regPos[0];
		float posY = lr.regPos[1];
		
		//draw the region
		_sb.draw(lr.getRegTex(), posX, posY);
		
		//draw the pointer
		if(_lastLr == lr) {
			_sb.draw(lr.getPointTex(), posX + lr.pointPos[0], posY + lr.pointPos[1]);
		}
		
		//draw the star
		if(Content.$().hasPassed(lvIdx)) {
			_sb.draw(_star, posX + lr.starPos[0], posY + lr.starPos[1]);
		}
	}

	private void update(float elapsedTime) {
		if(Gdx.input.justTouched()) {
			//Check touch for each level
			boolean found = false;
			updateTouchPoint();
			LevelDef[] lvs = Content.$().levels;
			int latestLevel = Content.$().latestLevel;
			for(int i = 0; i <= latestLevel; ++i) {
				LevelRep lr = lvs[i].levelRep;
				if(checkTouch(lr, _tempV3)) {
					found = true;
					GP.$().playClickSound();
					if(_lastLr == lr)
						gotoGameState(i);
					else
						_lastLr = lr;
					break;
				}
			}
			
			if(!found) _lastLr = null;
			
			//Check touch for exit
			if(_exitBtn.getBoundingRectangle().contains(_tempV3.x, _tempV3.y)) {
				requestStateChange(-1);
			}
		}
	}

	private void gotoGameState(int lvIdx) {
		getStateMgr().pushValueInExchangeBuff(new Integer(lvIdx));
		requestStateChange(new LoadingScreen(getStateMgr(), _sb, null, Content.$().levels[lvIdx].assetDecl, GP.$().STATE_GAME));
	}

	private boolean checkTouch(LevelRep lr, Vector3 touch) {
		_tempRect.set(lr.regPos[0], lr.regPos[1], lr.getRegTex().getRegionWidth(), lr.getRegTex().getRegionHeight());
		return _tempRect.contains(touch.x, touch.y);
	}
}
